package com.gci.lib_markdown_editor.viewer

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Build
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.webkit.*
import android.widget.FrameLayout
import androidx.webkit.WebViewAssetLoader
import java.io.File


class MarkdownView @JvmOverloads constructor(
    private val mContext: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : WebView(mContext, attrs, defStyleAttr) {

    var onFavoriteClicked: ((String, Long) -> Unit)? = null
    private val TAG = "MarkdownView"

    interface MarkdownListener {
        fun onUrlClicked(url: String?)
        fun onPageLoadFinished()
    }
    private var customView: View? = null
    private var customViewCallback: WebChromeClient.CustomViewCallback? = null
    private var mPreviewText: String? = null
    private var listener: MarkdownListener? = null
    private lateinit var assetLoader: WebViewAssetLoader
    private var rootDir: File? = null
    private var exportHtmlFile: File? = null

    /** 是否外部打开链接 */
    var isOpenUrlInBrowser = false

    init {
        initWebView()
    }

    private fun initWebView() {
        settings.javaScriptEnabled = true
        settings.allowFileAccess = true
        settings.allowContentAccess = true
        settings.domStorageEnabled = true
        settings.allowFileAccessFromFileURLs = true
        settings.mediaPlaybackRequiresUserGesture = false

        webChromeClient = object : WebChromeClient() {
            override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
                Log.d("WebViewConsole",
                    "${consoleMessage?.message() ?: ""} -- From line ${consoleMessage?.lineNumber()} of ${consoleMessage?.sourceId()}")
                return true
            }

            override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
                val activity = mContext as? Activity ?: return
                val decor = activity.window.decorView as FrameLayout

                // 添加全屏视图
                decor.addView(view, FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
                ))

                customView = view
                customViewCallback = callback

                // 设置横屏
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE

                // 隐藏系统 UI（可选）
                activity.window.decorView.systemUiVisibility =
                    View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            }

            override fun onHideCustomView() {
                val activity = mContext as? Activity ?: return
                val decor = activity.window.decorView as FrameLayout

                customView?.let {
                    decor.removeView(it)
                    customView = null
                    customViewCallback?.onCustomViewHidden()

                    // 恢复竖屏
                    activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

                    // 恢复系统 UI（可选）
                    activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
                }
            }
        }

        // 初始WebViewClient，assetLoader后面会替换
        webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                return try {
                    if (isOpenUrlInBrowser) {
                        mContext.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
                        true
                    } else {
                        listener?.onUrlClicked(url)
                        false
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    false
                }
            }
        }
    }

    /** 设置监听器 */
    fun setOnMarkdownListener(listener: MarkdownListener?) {
        this.listener = listener
    }

    /** 设置 Markdown 文本并准备注入 JS */
    fun setMarkDownText(markdownText: String) {
        val escaped = escapeForText(markdownText)
        mPreviewText = "preview('$escaped')"
    }

    /** 从 assets 读取 Markdown 文件并加载 */
    fun loadMarkdownFromAssets(assetPath: String) {
        try {
            val input = context.assets.open(assetPath)
            val reader = input.bufferedReader(Charsets.UTF_8)
            val content = reader.readText()
            reader.close()
            setMarkDownText(content)
        } catch (e: Exception) {
            Log.e(TAG, "读取 Assets 失败: $e")
        }
    }

    /** 从 File 加载 Markdown 文件并渲染 */
    fun loadMarkdownFromFile(file: File) {
        try {
            val content = file.readText()
            setMarkDownText(content)
        } catch (e: Exception) {
            Log.e(TAG, "读取文件失败: $e")
        }
    }

    /** Markdown 中的 JS 安全转义 */
    private fun escapeForText(mdText: String): String {
        return mdText
            .replace("\\", "\\\\")
            .replace("\n", "\\\\n")
            .replace("'", "\\'")
            .replace("\r", "")
    }

    /**
     * 从笔记专属文件夹加载预览页面和 markdown 内容
     * 这里必须把所有资源都放在 baseDir 目录（如 noteFolder/html/）
     * 访问 URL 必须用 https 伪协议开头，且匹配 assetLoader 映射路径
     */
    fun loadMarkdownFromNoteFolder(noteFolder: File, markdownFile: File) {
        // 注意：preview.html 必须放到 noteFolder/html/ 下
        val baseDir = File(noteFolder, "html")
        val previewHtmlFile = File(baseDir, "preview.html")
        if (!previewHtmlFile.exists()) {
            Log.e(TAG, "预览文件不存在: ${previewHtmlFile.absolutePath}")
            return
        }
        val exportFile = File(noteFolder, "rendered_export.html")

        setMarkdownBaseDirWithExport(baseDir, exportFile)

        // 加载预览页面，使用 assetLoader 映射的 https 路径
        loadUrl("https://appassets.androidplatform.net/local_files/preview.html")

        // 加载 markdown 内容（异步注入 JS）
        loadMarkdownFromFile(markdownFile)
    }

    /**
     * 设置本地资源映射和导出文件路径
     */
    fun setMarkdownBaseDirWithExport(baseDir: File, exportFile: File) {
        rootDir = baseDir
        exportHtmlFile = exportFile

        assetLoader = WebViewAssetLoader.Builder()
            .addPathHandler("/android_asset/", WebViewAssetLoader.AssetsPathHandler(context))
            .addPathHandler("/local_files/", MyFilePathHandler(baseDir))
            .build()

        webViewClient = object : WebViewClient() {
            override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest): WebResourceResponse? {
                val response = assetLoader.shouldInterceptRequest(request.url)
                return response ?: super.shouldInterceptRequest(view, request)
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                if (mPreviewText != null) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        evaluateJavascript(mPreviewText!!, null)
                        evaluateJavascript("bindImageClick();", null)
                        evaluateJavascript("bindFavoriteClick();", null)
                    } else {
                        loadUrl(mPreviewText!!)
                    }
                }
                listener?.onPageLoadFinished()
            }

            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                request?.url?.toString()?.let {
                    return try {
                        if (isOpenUrlInBrowser) {
                            mContext.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(it)))
                            true
                        } else {
                            listener?.onUrlClicked(it)
                            false
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                        false
                    }
                }
                return false
            }
        }

        exportHtmlFile?.let {
            addJavascriptInterface(JSBridge(it), "AndroidInterface")
        }
    }

    /** JS 回调：导出完整渲染后的 HTML 文件 */
    inner class JSBridge(private val outFile: File) {
        @JavascriptInterface
        fun onHtmlRendered(html: String) {
            try {
                outFile.writeText(html)
                Log.d(TAG, "✅ HTML 导出成功：${outFile.absolutePath}")
            } catch (e: Exception) {
                Log.e(TAG, "❌ 导出 HTML 失败: $e")
            }
        }

        @JavascriptInterface
        fun openImageFullScreen(imagePath: String) {
            try {
                val fullPath = File(rootDir, imagePath).absolutePath
                val intent = Intent(mContext, FullscreenImageActivity::class.java).apply {
                    putExtra("imagePath", fullPath)
                }
                mContext.startActivity(intent)
            } catch (e: Exception) {
                Log.e("MarkdownView", "打开图片失败：$imagePath", e)
            }
        }

        @JavascriptInterface
        fun onFavoriteClick(md5:String, pos:Long) {
            Log.i("MarkdownView", "onVideoClipClick：$md5/$pos")
            onFavoriteClicked?.invoke(md5, pos)
        }
    }



}
